package com.bjpowernode.dataservice.service;

import com.bjpowernode.commons.constants.RedisKey;
import com.bjpowernode.commons.constants.Status;
import com.bjpowernode.commons.service.BidInfoService;
import com.bjpowernode.commons.service.IncomeService;
import com.bjpowernode.commons.service.ProductService;
import com.bjpowernode.dataservice.mapper.ProductMapper;
import com.bjpowernode.commons.model.BidInfo;
import com.bjpowernode.commons.model.Income;
import com.bjpowernode.commons.model.Page;
import com.bjpowernode.commons.model.Product;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@DubboService // Spring创建实例并交给容器管理，并且发布到注册中心
public class ProductServiceImpl implements ProductService {

    @Resource
    private ProductMapper productMapper;

    @Resource
    @Lazy // 避免循环依赖
    private BidInfoService bidInfoService;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private IncomeService incomeService;


    // 每天凌晨3点执行：扫描达到返利要求的收益
    @Scheduled(cron = "0 0 3 * * ?")
    public void scanReturnMoney() {
        // 查询状态为0（未返利），且当前日期大于或等于返利时间income_date


    }

    // 每天凌晨2点执行：扫描满标产品，并生成收益计划
    @Scheduled(cron = "0 0 2 * * ?")
    public void scanFullProduct() {
        List<Product> products = productMapper.getFullProduct();
        if (products == null || products.size() == 0) {
            return ;
        }

        for (Product product : products) {
            // 查询当前产品的所有投资记录，并计算收益，添加收益计划
            List<BidInfo> bidInfos = bidInfoService.getBidInfoByProdId(product.getId());
            for (BidInfo bidInfo : bidInfos) {
                Income income = new Income();
                income.setUid(bidInfo.getUid());
                income.setProdId(product.getId());
                income.setBidId(bidInfo.getId());
                income.setIncomeStatus(0);
                income.setBidMoney(bidInfo.getBidMoney());

                // 计算收益金额：投资金额 * 产品年利率 / 100 / 12 * 产品周期
                Double incomeMoney = bidInfo.getBidMoney() * product.getRate() / 100 / 12 * product.getCycle();
                income.setIncomeMoney(incomeMoney);
                // 从产品的满标时间往后推迟产品周期个月
                Date fullTime = product.getProductFullTime();
                Integer cycle = product.getCycle();

                // 1. 假设按照1个月固定30天计算：
                // 日期的时间戳：距离1970年1月1日零晨0点的毫秒值
                //long time = fullTime.getTime();
                //long cycleTime = 1000 * 60 * 60 * 24 * 30 * cycle;
                //Date incomeDate = new Date(time + cycleTime);
                //income.setIncomeDate(incomeDate);

                // 2. 精准计算日期
                // 获取当前时间的日历
                Calendar calendar = Calendar.getInstance();
                // 以满标时间作为日历时间
                calendar.setTime(fullTime);
                // 在月份上进行加法计算
                calendar.add(Calendar.MONTH, cycle);
                Date incomeDate = calendar.getTime();
                income.setIncomeDate(incomeDate);
                incomeService.add(income);
            }

            // 修改产品状态为2：满标已生成收益计划
            productMapper.setStatus(product.getId(), Status.PRODUCT.FULL_PLAN);

        }
    }


    public Double getAvgRate() {

        ValueOperations valueOperations = redisTemplate.opsForValue();
        Double rate = (Double) valueOperations.get(RedisKey.PRO_RATE);
        if (rate == null) {
            rate = productMapper.getAvgRate();
            // 缓存1天
            valueOperations.set(RedisKey.PRO_RATE, rate, 1, TimeUnit.DAYS);
        }

        return rate;
    }

    public Product getNew() {
        return productMapper.getNew();
    }

    public List getYX() {
        /*return new ArrayList(){{
            add(productMapper.getYX(1)); // 满月宝
            add(productMapper.getYX(3)); // 季度宝
            add(productMapper.getYX(6)); // 双季宝
        }};*/

        List list = new ArrayList();
        list.add(productMapper.getYX(1)); // 满月宝
        list.add(productMapper.getYX(3)); // 季度宝
        list.add(productMapper.getYX(6)); // 双季宝
        return list;
    }

    public List getSB() {
        return productMapper.getSB();
    }

    @Value("${pageSize}")
    private Integer pageSize;

    @Override
    public Page getPage(Integer pageNum, Integer type) {

        // 计算总页数：(总记录数 - 1) / 每页显示条数 + 1
        // 查询总记录数
        Integer totalCount = productMapper.getCount(type);
        Integer pageCount = (totalCount - 1) / pageSize + 1;

        // 查询分页数据
        /*
            分页SQL（limit start, length）: 假设每页10条数据
            第1页：select * from xxx limit 0,10
            第2页：select * from xxx limit 10,10
            第3页：select * from xxx limit 20,10
            第4页：select * from xxx limit 30,10
            ...
            第n页：select * from xxx limit (n-1)*pageSize,pageSize
         */

        Integer start = (pageNum - 1) * pageSize;
        Integer length = pageSize;
        List data = productMapper.getPageData(type, start, length);

        Page page = new Page();
        page.setPageCount(pageCount);
        page.setData(data);

        return page;
    }

    public Product getById(Long id) {
        return productMapper.getById(id);
    }

    public int updateMoney(Long prodId, Double money) {
        return productMapper.updateMoney(prodId, money);
    }

    public void setFull(Long prodId, int status, Date fullTime) {
        productMapper.setFull(prodId, status, fullTime);
    }
}
